# used libraries
if (!require("ggplot2")) install.packages("ggplot2")
if (!require("plotly")) install.packages("plotly")
# R package DT provides an R interface to the JavaScript library DataTables.
if (!require("DT")) install.packages("DT")
# geom_mark_hull
if (!require("concaveman")) install.packages("concaveman")
if (!require("ggforce")) install.packages("ggforce")
# more libraries
if (!require("listviewer")) install.packages("listviewer")
if (!require("lubridate")) install.packages("lubridate")
if (!require("forcats")) install.packages("forcats")
if (!require("maps")) install.packages("maps")
if (!require("mvtnorm")) install.packages("mvtnorm")
if (!require("gapminder")) install.packages("gapminder")
if (!require("hexbin")) install.packages("hexbin")
if (!require("Hmisc")) install.packages("Hmisc")
if (!require("leaflet")) install.packages("leaflet")
if (!require("plotlyBook")) install.packages("plotlyBook")
This document is essentially a brief notes of the book above.
htmltools - Tools for creating, manipulating, and writing HTML from R.htmlwidget (on top htmltools) provides a framework for easily creating R bindings to JavaScript libraries. Widgets created using the framework can be:
crosstalk - provides building blocks for allowing HTML widgets to communicate with each other, with Shiny or without (i.e. static .html files).shiny - Web Application Framework for R, Makes it incredibly easy to build interactive web applications with Rplotly - interactive data visualizationDT, leaflet, …
DT - dataframe visualizationleaflet - geo mapsClient Side Linking means that (built-in) Browser handle all output/interactions using JavaScript/html tech.
Two components for highlighting:
highlight_key() function - set the selection option for higlight
highlight() this section shows you how to control how queries are triggered and visually rendered via the highlight() function.”“”
on/off - on which event to turn on/off highlighting, some possible events: “plotly_hover”, “plotly_click”, “plotly_doubleclick”selectize - turn on selectize.js powered dropdown widgetdynamic - should a widget for changing selection colors be included (add color)persistent - should selections persistlibrary(plotly)
head(mtcars)
mtcars_key <- highlight_key(mtcars, ~cyl)
p <- plot_ly(mtcars_key,
x = ~wt, y = ~mpg, text = ~cyl, mode = "markers+text",
textposition = "top", hoverinfo = "x+y"
)
highlight(p, on = "plotly_hover", off = "plotly_doubleclick")
## No trace type specified:
## Based on info supplied, a 'scatter' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#scatter
library(plotly)
head(mtcars)
mtcars %>%
highlight_key(~cyl) %>%
plot_ly(
x = ~wt, y = ~mpg, text = ~cyl, mode = "markers+text",
textposition = "top", hoverinfo = "x+y"
) %>%
highlight(on = "plotly_hover", off = "plotly_doubleclick")
## No trace type specified:
## Based on info supplied, a 'scatter' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#scatter
# load the `txhousing` dataset
data(txhousing, package = "ggplot2")
highlight_key(txhousing, ~city) %>% # declare `city` as highlight key
plot_ly(color = I("black")) %>%
group_by(city) %>%
add_lines(x = ~date, y = ~median)# create a time series of median house price
As it turns out, plotly makes it easy to add a selectize.js powered dropdown widget for querying by name (aka indirect manipulation) by setting selectize = TRUE.
highlight_key(txhousing, ~city) %>% # declare `city` as highlight key
plot_ly(color = I("black")) %>%
group_by(city) %>%
add_lines(x = ~date, y = ~median) %>%# create a time series of median house price
highlight(
on = "plotly_click",
selectize = TRUE,
dynamic = TRUE,
persistent = TRUE
)
## Adding more colors to the selection color palette.
## We recommend setting `persistent` to `FALSE` (the default) because persistent selection mode can now be used by holding the shift key (while triggering the `on` event).
## Setting the `off` event (i.e., 'plotly_doubleclick') to match the `on` event (i.e., 'plotly_click'). You can change this default via the `highlight()` function.
# remember, `base` is a plotly object, but we can use dplyr verbs to
# manipulate the input data
# (`txhousing` with `city` as a grouping and querying variable)
base <- highlight_key(txhousing, ~city) %>% # declare `city` as highlight key
plot_ly(color = I("black")) %>%
group_by(city)
dot_plot <- base %>%
summarise(miss = sum(is.na(median))) %>%
filter(miss > 0) %>%
add_markers(
x = ~miss,
y = ~forcats::fct_reorder(city, miss),
hoverinfo = "x+y"
) %>%
layout(
xaxis = list(title = "Number of months missing"),
yaxis = list(title = "")
)
time_series <- base %>%
group_by(city) %>%
add_lines(x = ~date, y = ~median)
subplot(dot_plot, time_series, widths = c(.2, .8), titleX = TRUE) %>%
layout(showlegend = FALSE) %>%
highlight(on = "plotly_click", dynamic = TRUE, selectize = TRUE)
## Adding more colors to the selection color palette.
## Setting the `off` event (i.e., 'plotly_doubleclick') to match the `on` event (i.e., 'plotly_click'). You can change this default via the `highlight()` function.
hist <- add_histogram(
base,
x = ~median,
histnorm = "probability density"
)
subplot(time_series, hist, nrows = 2) %>%
layout(barmode = "overlay", showlegend = FALSE) %>%
highlight(
dynamic = TRUE,
selectize = TRUE,
selected = attrs_selected(opacity = 0.3)
)
## Adding more colors to the selection color palette.
## Setting the `off` event (i.e., 'plotly_doubleclick') to match the `on` event (i.e., 'plotly_click'). You can change this default via the `highlight()` function.
Other htmlwidgets can be combined together
library(plotly)
m <- highlight_key(mpg)
p <- ggplot(m, aes(displ, hwy)) + geom_point()
gg <- highlight(ggplotly(p), "plotly_selected")
# arrange widgets in columns (from crosstalk)
crosstalk::bscols(gg, DT::datatable(m))
## Setting the `off` event (i.e., 'plotly_deselect') to match the `on` event (i.e., 'plotly_selected'). You can change this default via the `highlight()` function.
filter_select(),
library(crosstalk)
# highlight
tx <- highlight_key(txhousing, ~city, "Select a city")
gg <- ggplot(tx) + geom_line(aes(date, median, group = city))
highlight_p <- highlight(
ggplotly(gg, tooltip = "city"),
selectize = TRUE, persistent = TRUE
)
## We recommend setting `persistent` to `FALSE` (the default) because persistent selection mode can now be used by holding the shift key (while triggering the `on` event).
# filter
# generally speaking, use a "unique" key for filter,
# especially when you have multiple filters!
tx2 <- highlight_key(txhousing)
gg2 <- ggplot(tx2) + geom_line(aes(date, median, group = city))
# arrange widgets in columns (from crosstalk)
filter_p <- bscols(
filter_select("id", "Select a city", tx2, ~city),
ggplotly(gg2, dynamicTicks = TRUE),
widths = c(12, 12)
)
# arrange widgets in columns (from crosstalk)
bscols(highlight_p, filter_p)
## Setting the `off` event (i.e., 'plotly_doubleclick') to match the `on` event (i.e., 'plotly_click'). You can change this default via the `highlight()` function.
library(crosstalk)
tx <- highlight_key(txhousing)
widgets <- bscols(
widths = c(12, 12, 12),
filter_select("city", "Cities", tx, ~city),
filter_slider("sales", "Sales", tx, ~sales),
filter_checkbox("year", "Years", tx, ~year, inline = TRUE)
)
bscols(
widths = c(4, 8), widgets,
plot_ly(tx, x = ~date, y = ~median, showlegend = FALSE) %>%
add_lines(color = ~city, colors = "black")
)
filter and highlight events can work in conjunction with various htmlwidgets. In fact, since the semantics of filter are more well-defined than highlight, linking filter events across htmlwidgets via crosstalk should generally be more well-supported.
library(leaflet)
eqs <- highlight_key(quakes)
stations <- filter_slider(
"station", "Number of Stations",
eqs, ~stations
)
p <- plot_ly(eqs, x = ~depth, y = ~mag) %>%
add_markers(alpha = 0.5) %>%
highlight("plotly_selected")
map <- leaflet(eqs) %>%
addTiles() %>%
addCircles()
## Assuming "long" and "lat" are longitude and latitude, respectively
bscols(
widths = c(6, 6, 3),
p, map, stations
)
## Setting the `off` event (i.e., 'plotly_deselect') to match the `on` event (i.e., 'plotly_selected'). You can change this default via the `highlight()` function.
library(gapminder)
g <- highlight_key(gapminder, ~country)
continent_filter <- filter_select(
"filter", "Select a country",
g, ~continent
)
p <- plot_ly(g) %>%
group_by(country) %>%
add_lines(x = ~year, y = ~lifeExp, color = ~continent) %>%
layout(xaxis = list(title = "")) %>%
highlight(selected = attrs_selected(showlegend = FALSE))
bscols(continent_filter, p, widths = 12)
## Setting the `off` event (i.e., 'plotly_doubleclick') to match the `on` event (i.e., 'plotly_click'). You can change this default via the `highlight()` function.
g <- highlight_key(gapminder, ~continent)
gg <- ggplot(g, aes(gdpPercap, lifeExp,
color = continent, frame = year)) +
geom_point(aes(size = pop, ids = country)) +
geom_smooth(se = FALSE, method = "lm") +
scale_x_log10()
highlight(ggplotly(gg), "plotly_click")
## `geom_smooth()` using formula 'y ~ x'
## Setting the `off` event (i.e., 'plotly_doubleclick') to match the `on` event (i.e., 'plotly_click'). You can change this default via the `highlight()` function.
library(gapminder)
# gapKey <- highlight_key(gap, ~country)
gap <- gapminder %>% mutate(country=forcats::fct_reorder(as.character(country), pop)) # forcats::fct_reorder for factor reorder
levels(gap$country)
## [1] "Sao Tome and Principe" "Iceland"
## [3] "Djibouti" "Equatorial Guinea"
## [5] "Comoros" "Bahrain"
## [7] "Reunion" "Montenegro"
## [9] "Swaziland" "Gambia"
## [11] "Gabon" "Guinea-Bissau"
## [13] "Botswana" "Mauritius"
## [15] "Namibia" "Trinidad and Tobago"
## [17] "Oman" "Kuwait"
## [19] "Lesotho" "West Bank and Gaza"
## [21] "Mauritania" "Mongolia"
## [23] "Congo, Rep." "Slovenia"
## [25] "Liberia" "Panama"
## [27] "Jordan" "Jamaica"
## [29] "Costa Rica" "Central African Republic"
## [31] "Togo" "Singapore"
## [33] "Eritrea" "Albania"
## [35] "Nicaragua" "Uruguay"
## [37] "Libya" "Lebanon"
## [39] "Paraguay" "Puerto Rico"
## [41] "New Zealand" "Sierra Leone"
## [43] "Honduras" "Ireland"
## [45] "Benin" "Israel"
## [47] "Bosnia and Herzegovina" "Norway"
## [49] "Burundi" "Croatia"
## [51] "El Salvador" "Guinea"
## [53] "Chad" "Finland"
## [55] "Hong Kong, China" "Slovak Republic"
## [57] "Haiti" "Rwanda"
## [59] "Somalia" "Denmark"
## [61] "Bolivia" "Dominican Republic"
## [63] "Zambia" "Senegal"
## [65] "Guatemala" "Niger"
## [67] "Malawi" "Burkina Faso"
## [69] "Tunisia" "Switzerland"
## [71] "Angola" "Mali"
## [73] "Zimbabwe" "Cambodia"
## [75] "Austria" "Ecuador"
## [77] "Bulgaria" "Cote d'Ivoire"
## [79] "Sweden" "Madagascar"
## [81] "Cameroon" "Syria"
## [83] "Serbia" "Yemen, Rep."
## [85] "Greece" "Cuba"
## [87] "Saudi Arabia" "Portugal"
## [89] "Belgium" "Czech Republic"
## [91] "Hungary" "Ghana"
## [93] "Chile" "Mozambique"
## [95] "Uganda" "Iraq"
## [97] "Afghanistan" "Malaysia"
## [99] "Netherlands" "Venezuela"
## [101] "Australia" "Sri Lanka"
## [103] "Nepal" "Kenya"
## [105] "Korea, Dem. Rep." "Peru"
## [107] "Taiwan" "Tanzania"
## [109] "Algeria" "Sudan"
## [111] "Morocco" "Romania"
## [113] "Canada" "Colombia"
## [115] "Argentina" "Congo, Dem. Rep."
## [117] "South Africa" "Myanmar"
## [119] "Poland" "Ethiopia"
## [121] "Spain" "Korea, Rep."
## [123] "Iran" "Egypt"
## [125] "Turkey" "Thailand"
## [127] "Philippines" "Vietnam"
## [129] "France" "United Kingdom"
## [131] "Italy" "Nigeria"
## [133] "Mexico" "Germany"
## [135] "Pakistan" "Bangladesh"
## [137] "Japan" "Brazil"
## [139] "Indonesia" "United States"
## [141] "India" "China"
plot_ly(gap, y = ~factor(country), x = ~pop, hoverinfo = "x") %>%
add_markers(alpha = 0.1, color = I("black"))
gap <- gapminder %>% mutate(country=forcats::fct_reorder(as.character(country), pop))
# forcats::fct_reorder for factor reorder
gapKey <- highlight_key(gap, ~country)
p1 <- plot_ly(gap, y = ~country, x = ~pop, hoverinfo = "text") %>%
add_markers(alpha = 0.1,text=paste(gap$country,gap$pop), color = I("black")) %>%
add_markers(
data = gapKey,
frame = ~year,
ids = ~country,
text=paste(gap$country,gap$pop),
color = I("red")
) %>%
layout(xaxis = list(type = "log"))
p2 <- plot_ly(gap, x = ~gdpPercap, y = ~lifeExp,
text = ~country, hoverinfo = "text") %>%
add_markers(color = I("black"), alpha = 0.1) %>%
add_markers(
data = gapKey,
frame = ~year,
ids = ~country,
color = I("red")
) %>%
layout(xaxis = list(type = "log"))
subplot(p1, p2, nrows = 1, widths = c(0.3, 0.7), titleX = TRUE) %>%
hide_legend() %>%
animation_opts(1000, redraw = FALSE) %>%
layout(hovermode = "y", margin = list(l = 100)) %>%
highlight(
"plotly_selected",
color = "blue",
opacityDim = 1,
hoverinfo = "none"
)
## Setting the `off` event (i.e., 'plotly_deselect') to match the `on` event (i.e., 'plotly_selected'). You can change this default via the `highlight()` function.